<?php
// $Id: regblocks.pages.inc,v 1.4 2010/09/24 12:09:35 coornail Exp $

/**
 * Page callback for admin/settings/regblocks
 *
 * @return string
 */
function regblocks_list_page() {
  $header = array(
    t('Name'),
    t('Destination'),
    t('Profile'),
    '&nbsp;',
    '&nbsp;',
    '&nbsp;',
  );
  $rows = array();
  $regblocks = regblock_load_all();
  foreach($regblocks as $regblock) {
    $rows []= array(
      check_plain($regblock->alias),
      check_plain($regblock->target),
      $regblock->formdata->settings->profile ? t('Yes') : t('No'),
      l(t('Edit'), 'admin/settings/regblocks/edit/'.$regblock->rbid),
      l(t('Delete'), 'admin/settings/regblocks/delete/'.$regblock->rbid),
      l(t('Export'), 'admin/settings/regblocks/export/'.$regblock->rbid),
    );
  }
  return theme('table', $header, $rows) . drupal_get_form('regblocks_settings_form');
}

/**
 * Settings form for some advanced settings.
 *
 * @param array $form
 * @return array
 */
function regblocks_settings_form($form) {
  $f = array();

  $f['regblocks_advanced_settings_fieldset'] = array(
    '#type' => 'fieldset',
    '#title' => t('Advanced settings'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );

  $f['regblocks_advanced_settings_fieldset']['regblocks_allow_rename_submit_buttons'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow renaming of the submit buttons'),
    '#default_value' => variable_get('regblocks_allow_rename_submit_buttons', FALSE),
  );

  $f['regblocks_advanced_settings_fieldset']['regblock_hidden_field_type'] = array(
    '#type' => 'radios',
    '#title' => t('Hidden field type'),
    '#default_value' => variable_get('regblocks_hidden_field_type', 'value'),
    '#options' => array(
      'value' => t('Value'),
      'hidden' => t('Hidden'),
    ),
  );

  $f['regblocks_advanced_settings_fieldset']['regblocks_threat_new_fields_as_hidden'] = array(
    '#type' => 'checkbox',
    '#title' => t('Threat new fields as hidden'),
    '#default_value' => variable_get('regblocks_threat_new_fields_as_hidden', TRUE),
  );

  $f['regblocks_advanced_settings_fieldset']['regblocks_force_enable_password'] = array(
    '#type' => 'checkbox',
    '#title' => t('Force enable password fields'),
    '#default_value' => variable_get('regblocks_force_enable_password', FALSE),
  );

  if(module_exists('content_profile_registration')) {
    $f['regblocks_advanced_settings_fieldset']['regblocks_disable_content_profile'] = array(
      '#type' => 'checkbox',
      '#title' => t('Disable content profile support'),
      '#default_value' => variable_get('regblocks_disable_content_profile', FALSE),
    );
  }

  $f = system_settings_form($f);
  $f['regblocks_advanced_settings_fieldset']['buttons'] = $f['buttons'];
  unset($f['buttons']);

  return $f;
}

/**
 * Add and edit form for a regblock.
 *
 * @param array $form
 * @param stdClass $regblock
 * @return array
 */
function regblocks_edit_form($form, $regblock = NULL) {
  $f = array();

  if($regblock === NULL) {
    $regblock = new stdClass();
  }

  $f['rbid'] = array(
    '#type' => 'value',
    '#value' => isset($regblock->rbid) ? $regblock->rbid : NULL,
  );

  $f['alias'] = array(
    '#type' => 'textfield',
    '#title' => t('Name of the block'),
    '#required' => TRUE,
    '#maxlength' => 255,
    '#default_value' => isset($regblock->alias) ? $regblock->alias : '',
  );

  $f['target'] = array(
    '#type' => 'textfield',
    '#title' => t('Target path'),
    '#maxlength' => 255,
    '#default_value' => isset($regblock->target) ? $regblock->target : '',
  );

  $rbf = new RegblocksFields(regblocks_get_reg_form());
  $reqfields = $rbf->getRequiredFields();
  $optfields = $rbf->getOptionalFields();
  $default_fields = array();
  $first_time = !isset($regblock->formdata->optfields);
  foreach($optfields as $k=>$v) {
    $default_fields[$k] = isset($regblock->formdata->optfields[$k]) ? $regblock->formdata->optfields[$k] : $first_time;
    if($default_fields[$k]) {
      $default_fields[$k] = $k;
    }
  }

  $f['optfields'] = array(
    '#type' => 'fieldset',
    '#title' => t('Optional fields'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );

  if(empty($optfields)) {
    $f['optfields']['nofields'] = array(
      '#type' => 'markup',
      '#value' => t('You don\'t have any additional fields to display on the registration form.'),
    );
  } else {
    $f['optfields']['fields'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Enabled fields'),
      '#options' => $optfields,
      '#default_value' => $default_fields,
    );
  }

  $f['labels'] = array(
    '#type' => 'fieldset',
    '#title' => t('Label overrides'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );

  $allfields = $optfields + $reqfields;

  if(variable_get('regblocks_allow_rename_submit_buttons', FALSE)) {
    $allfields += array('submit' => 'Submit');
  }

  foreach($allfields as $name => $label) {
    $f['labels']['label-'.$name] = array(
      '#type' => 'textfield',
      '#title' => t($label),
      '#default_value' => isset($regblock->formdata->labels[$name]) ?
        $regblock->formdata->labels[$name] : '',
    );
  }

  $f['settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Settings'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );

  $f['settings']['profile'] = array(
    '#type' => 'checkbox',
    '#title' => t('Use as profile edit teaser'),
    '#default_value' => $regblock->formdata->settings->profile,
  );

  $f['settings']['profile_submit'] = array(
    '#type' => 'textfield',
    '#title' => t('Submit button label'),
    '#default_value' => isset($regblock->formdata->settings->submit) ?
      $regblock->formdata->settings->submit : '',
  );

  $f['settings']['terms_and_conditions'] = array(
    '#type' => 'textarea',
    '#title' => t('Terms and conditions'),
    '#default_value' => isset($regblock->formdata->settings->terms_and_conditions) ?
      $regblock->formdata->settings->terms_and_conditions : '',
  );

  $f['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );

  $f['#redirect'] = 'admin/settings/regblocks';

  return $f;
}

/**
 * Validate function for regblocks_edit_form().
 */
function regblocks_edit_form_validate($form, &$form_state) {
  ;
}

/**
 * Submit function for regblocks_edit_form().
 */
function regblocks_edit_form_submit($form, &$form_state) {
  $regblock = new stdClass();
  $v =& $form_state['values'];
  if($v['rbid']) {
    $regblock->rbid = $v['rbid'];
  }
  $regblock->alias = $v['alias'];
  $regblock->formdata = new stdClass();

  $regblock->formdata->optfields = array();
  if (!empty($v['fields'])) {
    foreach($v['fields'] as $field => $val) {
      $regblock->formdata->optfields[$field] = (bool)$val;
    }
  }

  $regblock->formdata->labels = array();
  foreach($v as $name => $label) {
    if(strpos($name, 'label-') === 0) {
      $regblock->formdata->labels[substr($name, 6)] = $label;
    }
  }

  $regblock->formdata->settings = new stdClass();
  $regblock->formdata->settings->profile = (bool)$v['profile'];
  $regblock->formdata->settings->submit = $v['profile_submit'];
  $regblock->formdata->settings->terms_and_conditions = $v['terms_and_conditions'];

  $regblock->target = $v['target'];
  regblock_save($regblock);
  cache_clear_all(); // TODO: watch out for performance
}

/**
 * Delete form for a regblock.
 *
 * @param array $form
 * @param stdClass $regblock
 */
function regblocks_delete_form($form, $regblock) {
  $f = array();
  $f['rbid'] = array(
    '#type' => 'value',
    '#value' => $regblock->rbid,
  );

  $f['#redirect'] = 'admin/settings/regblocks';

  return confirm_form($f,
    t('Are you sure that you want to delete the block?'),
    'admin/settings/regblocks',
    t('This action cannot be undone'),
    t('Delete'),
    t('Cancel')
  );
}

/**
 * Submit function for regblocks_delete_form().
 *
 * @param array $form_state
 * @param array $form
 */
function regblocks_delete_form_submit($form_state, $form) {
  db_query('DELETE FROM {regblock} WHERE rbid = %d', $form_state['rbid']['#value']);
}

/**
 * Returns the user registration form
 * in a way that an anonymous user can see.
 *
 * Warning: this function may hurt your kittens.
 *
 * @global stdClass $user
 * @return array
 */
function regblocks_get_reg_form() {
  global $user;

  // this is here to prevent the infinite loop with form alters
  $switch = &ctools_static('regblocks_formalter_switch');
  $switch = TRUE;

  $original_user = $user;
  $anonymous_user = user_load(0);

  $user = $anonymous_user;

  $form_state = array('storage' => NULL, 'submitted' => FALSE);
  $form = drupal_retrieve_form('user_register', $form_state);
  drupal_prepare_form('user_register', $form, $form_state);

  $user = $original_user;

  $switch = FALSE;

  return $form;
}

/**
 * Class to extract extra fields from the registration form.
 */
class RegblocksFields {

  /**
   * Form array, returned by drupal_retrieve_form().
   *
   * @var array
   */
  protected $form;

  /**
   * Associative array of the required fields.
   *
   * @var array
   */
  protected $reqfields;

  /**
   * Associative array of the optional fields.
   *
   * @var array
   */
  protected $optfields;

  /**
   * Constructor.
   *
   * @param array $form
   */
  public function __construct($form) {
    $this->form = $form;
  }

  /**
   * Checks if the type of the actual field is OK.
   *
   * @staticvar array $invalid_types
   * @param string $type
   * @return bool
   */
  protected function checkType($type) {
    $invalid_types = regblocks_form_invalid_types();
    return !in_array($type, $invalid_types);
  }

  /**
   * Recursively walks the form and collect fields.
   *
   * @param array $subform
   * @param string $key
   */
  protected function discover($subform, $key = NULL) {
    if(!is_array($subform)) return;
    if($key !== NULL &&
            isset($subform['#title']) &&
            isset($subform['#type']) && $this->checkType($subform['#type'])
            ) {
      if(isset($subform['#required']) && $subform['#required']) {
        $this->reqfields[$key] = $subform['#title'];
      } else {
        $this->optfields[$key] = $subform['#title'];
      }
    }
    foreach($subform as $k => $v) {
      if(is_array($v)) {
        $this->discover($v, $k);
      }
    }
  }

  /**
   * Returns the list of the required fields.
   *
   * @return array
   */
  public function getRequiredFields() {
    if(!isset($this->fields)) {
      $this->reqfields = array();
      $this->optfields = array();
      $this->discover($this->form);
    }
    return $this->reqfields;
  }

  /**
   * Returns the list of the optional fields.
   *
   * @return array
   */
  public function getOptionalFields() {
    if(!isset($this->optfields)) {
      $this->reqfields = array();
      $this->optfields = array();
      $this->discover($this->form);
    }
    return $this->optfields;
  }
}

/**
 * Export form for a regblock.
 *
 * @param array $form
 * @param stdClass $regblock
 * @return string
 */
function regblocks_export_form($regblock) {
  ctools_include('export');
  $code = regblock_export($regblock);
  return drupal_get_form('ctools_export_form', $code, check_plain($regblock->alias));
}

/**
 * Import form for a regblock.
 *
 * @param array $form
 * @return array
 */
function regblocks_import_form($form) {
  $f = array();

  $f['object'] = array(
    '#type' => 'textarea',
    '#title' => t('Please paste the code here'),
  );

  return $f;
}

/**
 * Validation callback for regblocks_import_form().
 *
 * @param array $form
 * @param array $form_state
 */
function regblocks_import_form_validate($form, &$form_state) {
  ob_start();
  eval($form_state['values']['object']);
  ob_end_clean();

  if(empty($regblock)) {
    $errors = ob_get_contents();
    if(empty($errors)) {
      $errors = t('No object found.');
    }

    form_set_error('object', t('Unable to get a regblock from the import. Errors reported: @errors.', array(
      '@errors' => $errors,
    )));
  }

  $form_state['regblock'] = $regblock;
}

/**
 * Submit function for regblocks_import_form().
 *
 * @param array $form
 * @param array $form_state
 */
function regblocks_import_form_submit($form, &$form_state) {
  $regblock = $form_state['regblock'];

  regblock_save($regblock);

  $form_state['#redirect'] = 'admin/settings/regblocks';
}
